using QFramework;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityTemplateProjects;

public class AdvancedCameraController : SimpleCameraController, IController
{
    [SerializeField]
    private List<Transform> monitorTransforms;

    [SerializeField]
    private Transform followingTarget;

    private BaseCameraControllerState m_State;

    protected override void OnEnable()
    {
        base.OnEnable();
        ChangeState(new CameraMoveState());
        this.RegisterEvent<FollowVehicleEvent>(FollowTargetVehicle).UnRegisterWhenGameObjectDestroyed(this);
        this.RegisterEvent<EndFollowVehicleEvent>(EndFollowTargetVehicle).UnRegisterWhenGameObjectDestroyed(this);
    }

    private void EndFollowTargetVehicle(EndFollowVehicleEvent e)
    {
        if (followingTarget && e.vehicle.Find("CameraFollow") == followingTarget)
        {
            followingTarget = null;
            ChangeState(new CameraMoveState());
        }
    }

    private void FollowTargetVehicle(FollowVehicleEvent e)
    {
        followingTarget = e.vehicle.Find("CameraFollow");
        ChangeState(new CameraFollowState(followingTarget));
    }


    protected override void Update()
    {
        if (monitorTransforms != null && monitorTransforms.Count <= 5)
        {
            if (Input.GetKeyDown(KeyCode.Alpha1))
            {
                ChangeState(new CameraJumpState(monitorTransforms[0]));
            }
            if (Input.GetKeyDown(KeyCode.Alpha2))
            {
                ChangeState(new CameraJumpState(monitorTransforms[1]));
            }
            if (Input.GetKeyDown(KeyCode.Alpha3))
            {
                ChangeState(new CameraJumpState(monitorTransforms[2]));
            }
            if (Input.GetKeyDown(KeyCode.Alpha4))
            {
                ChangeState(new CameraJumpState(monitorTransforms[3]));
            }
            if (Input.GetKeyDown(KeyCode.Alpha5))
            {
                ChangeState(new CameraJumpState(monitorTransforms[4]));
            }
        }
        if (Input.GetMouseButtonUp(0))
        {
            this.GetSystem<ISelectItemSystem>().SingleSelection();
        }
        m_State?.OnUpdate();
    }

    void ChangeState(BaseCameraControllerState state)
    {
        m_State?.OnExit();
        m_State = state.SetContext(this);
        m_State?.OnEnter();
    }
    void BaseUpdate()
    {
        base.Update();
    }

    public IArchitecture GetArchitecture()
    {
        return DigitalTwin_GeLinMei_2.Interface;
    }

    abstract class BaseCameraControllerState
    {
        public AdvancedCameraController Context;
        public BaseCameraControllerState() { }
        public BaseCameraControllerState SetContext(AdvancedCameraController Context)
        {
            this.Context = Context;
            return this;
        }
        public abstract void OnEnter();
        public abstract void OnExit();
        public abstract void OnUpdate();
    }
    class CameraJumpState : BaseCameraControllerState
    {
        Transform m_Target;
        public CameraJumpState(Transform t)
        {
            m_Target = t;
        }
        public override void OnEnter()
        {
            Context.m_TargetCameraState.SetFromTransform(m_Target);
            Context.ChangeState(new CameraMoveState());
        }
        public override void OnExit()
        {

        }
        public override void OnUpdate()
        {
        }
    }
    class CameraMoveState : BaseCameraControllerState
    {
        public CameraMoveState() { }
        public override void OnEnter() { }
        public override void OnExit() { }
        public override void OnUpdate()
        {
            Context.BaseUpdate();
        }
    }
    class CameraFollowState : BaseCameraControllerState
    {
        Transform m_Follow;
        public CameraFollowState(Transform t)
        {
            m_Follow = t;
        }
        public override void OnEnter()
        {

        }
        public override void OnExit()
        {

        }
        public override void OnUpdate()
        {
            Cursor.visible = true;
            Cursor.lockState = CursorLockMode.None;

            Context.m_TargetCameraState.SetFromTransform(m_Follow);
            var positionLerpPct = 1f - Mathf.Exp((Mathf.Log(1f - 0.99f) / 1) * Time.deltaTime);
            var rotationLerpPct = 1f - Mathf.Exp((Mathf.Log(1f - 0.99f) / 1) * Time.deltaTime);


            Context.m_InterpolatingCameraState.LerpTowards(Context.m_TargetCameraState, positionLerpPct, rotationLerpPct);
            Context.m_InterpolatingCameraState.UpdateTransform(Context.transform);
        }
    }
}
